﻿/*
* ========================================================================
* 类说明：
*   
* 
* 作者：HGS   时间：2024/9/5 10:11:49
* 
* 修改者：         时间：           
* 修改说明：
* ========================================================================
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PopupWinTool.Common
{
    /// <summary>
    /// 说明：
    ///     常规日志：yyyyMMdd.txt，写入的日志类型为 Debug、Info、Error
    ///     命令日志：yyyyMMdd_Command.txt，即接口交互日志，写入的日志类型为 Command
    /// </summary>
    public class LogHelper
    {
        /// <summary>
        /// 日志文件默认路径
        /// </summary>
        public static string LogPath = $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")}";

        /// <summary>
        /// 写入调试日志
        /// </summary>
        /// <param name="content">[send]... or [receive]...</param>
        public static void Debug(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + ".txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}  [Debug]{content}\r\n";
            Write(content, path);
        }
        /// <summary>
        /// 写入调试日志
        /// </summary>
        /// <param name="content">[send]... or [receive]...</param>
        /// <param name="args"></param>
        public static void DebugFormat(string content, params object[] args)
        {
            content = string.Format(content, args);
            Debug(content);
        }
        /// <summary>
        /// 写一般信息日志
        /// </summary>
        /// <param name="content"></param>
        public static void Info(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + ".txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}   [Info]{content}\r\n";
            Write(content, path);
        }
        /// <summary>
        /// 写一般信息日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="args"></param>
        public static void InfoFormat(string content, params object[] args)
        {
            content = string.Format(content, args);
            Info(content);
        }
        /// <summary>
        /// 写错误日志
        /// </summary>
        /// <param name="content"></param>
        public static void Error(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + ".txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}  [Error]{content}\r\n";
            Write(content, path);
        }
        /// <summary>
        /// 写错误日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="ex"></param>
        public static void Error(string content, Exception ex)
        {
            content = $"{content}。{ex.StackTrace}";
            Error(content);
        }
        /// <summary>
        /// 写错误日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="args"></param>
        public static void ErrorFormat(string content, params object[] args)
        {
            content = string.Format(content, args);
            Error(content);
        }
        /// <summary>
        /// 记录接口交互日志
        /// </summary>
        /// <param name="content"></param>
        public static void Command(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + "_Command.txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}  {content}\r\n";
            Write(content, path);
        }
        /// <summary>
        /// 记录接口交互日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="args"></param>
        public static void CommandFormat(string content, params object[] args)
        {
            content = string.Format(content, args);
            Command(content);
        }
        /// <summary>
        /// 写警告日志
        /// </summary>
        /// <param name="content"></param>
        public static void Warn(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + ".txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}   [Warn]{content}\r\n";
            Write(content, path);
        }
        /// <summary>
        /// 写运行日志
        /// </summary>
        /// <param name="content"></param>
        public static void Run(string content)
        {
            string path = $"{Path.Combine(LogPath, DateTime.Now.ToString("yyyyMMdd") + "_Run.txt")}";
            if (!Directory.Exists(LogPath))
            {
                try
                {
                    Directory.CreateDirectory(LogPath);
                }
                catch { return; }
            }
            content = $"{DateTime.Now.ToString("HH:mm:ss.fff")}   {content}\r\n";
            Write(content, path);
        }


        /// <summary>
        /// 将文本内容追加到指定文件中
        /// </summary>
        /// <param name="content">写入内容</param>
        /// <param name="filePath">文件路径值</param>
        private static void Write(string content, string filePath)
        {
            try
            {
                //限制日志文件大小
                if (File.Exists(filePath))
                {
                    var fileInfo = new FileInfo(filePath);
                    if (fileInfo.Length > 10 * 1024 * 1024)
                    {
                        int i = 1;
                        while (true)
                        {
                            string fileName = Path.GetFileNameWithoutExtension(filePath);
                            string directoryName = Path.GetDirectoryName(filePath);
                            string path = $"{Path.Combine(directoryName, $"{fileName}_{i}" + ".txt")}";
                            if (File.Exists(path))
                            {
                                i++;
                            }
                            else
                            {
                                fileInfo.MoveTo(path);
                                break;
                            }
                            Thread.Sleep(1);
                        }
                    }
                }

                //写入数据
                using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                {
                    //byte[] bt = Encoding.UTF8.GetBytes(content);
                    byte[] bt = Encoding.Default.GetBytes(content);
                    fs.Write(bt, 0, bt.Length);
                    fs.Close();
                }
            }
            catch { }
        }
        /// <summary>
        /// 删除旧日志
        /// </summary>
        /// <param name="days">日志允许保留的与当前时间间隔的最大天数，默认为7天</param>
        public static void DeleteOldLog(int days = 7)
        {
            try
            {
                //确定文件夹是否存在
                if (!Directory.Exists(LogPath))
                {
                    return;
                }

                //获取文件夹下所有日志文件
                string[] fileList = Directory.GetFiles(LogPath, "*.txt");
                List<string> removeList = new List<string>();
                DateTime dtNow = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
                foreach (var file in fileList)
                {
                    DateTime fileDate = DateTime.MaxValue;
                    string fileName = Path.GetFileName(file);
                    if (fileName.Length < 8)
                    {
                        continue;  //文件名称不符合指定长度，跳到下一个
                    }

                    //将文件名日期前缀转换未DateTime格式数据
                    //string dateTemp = fileName.Substring(0, 4) + "/" + fileName.Substring(4, 2) + "/" + fileName.Substring(6, 2);
                    string dateTemp = $"{fileName.Substring(0, 4)}/{fileName.Substring(4, 2)}/{fileName.Substring(6, 2)}";
                    if (!DateTime.TryParse(dateTemp, out fileDate))
                        continue;  //时间转换失败，跳到下一个

                    if ((dtNow - fileDate).TotalDays > days)
                    {
                        removeList.Add(file);  //超过保留天数的日志文件，记录到待删除列表中
                    }
                }

                //删除超期日志文件
                if (removeList.Count > 0)
                {
                    foreach (var filePath in removeList)
                    {
                        File.Delete(filePath);
                    }
                }
            }
            catch (Exception ex)
            {
                Error($"删除旧日志异常，{ex.Message}。\r\n{ex.StackTrace}");
            }
        }
    }
}
